﻿using Admin.ApplicationLib.Entities;
using Admin.CommonLib.Models.Permission;
using Ardalis.Specification.EntityFrameworkCore;
using LinqKit;
using Microsoft.EntityFrameworkCore;

namespace Admin.ApplicationLib.Repositories
{
    public class PermissionRepository : RepositoryBase<PermissionEntity>, IPermissionRepository
    {
        private readonly AdminApplicationDbContext _dbContext;

        public PermissionRepository(AdminApplicationDbContext dbContext) : base(dbContext)
        {
            _dbContext = dbContext;
        }

        public async Task<Tuple<IList<PermissionEntity>, int>> QueryByPageAsync(PermissionSearchRequestDto model)
        {
            var predicate = PredicateBuilder.New<PermissionEntity>(true);

            predicate = predicate.And(p => p.ParentId == model.ParentId);

            if (!string.IsNullOrEmpty(model.PermissionCode))
            {
                predicate = predicate.And(p => p.Code != null && p.Code.Contains(model.PermissionCode));
            }

            if (!string.IsNullOrEmpty(model.PermissionName))
            {
                predicate = predicate.And(p => p.Name != null && p.Name.Contains(model.PermissionName));
            }

            var query = _dbContext.Permissions!
                .Where(predicate);

            var totalCount = query.Count();
            var aggregates = await query.OrderBy(i => i.Sort)
                .Skip((model.Page - 1) * model.Limit).Take(model.Limit).ToListAsync();
            return new Tuple<IList<PermissionEntity>, int>(aggregates, totalCount);
        }

        public async Task<IList<PermissionEntity>> QueryByUserAsync(Guid userId, int treeType)
        {
            return await (from permission in _dbContext.Permissions
                join roleClaim in _dbContext.RoleClaims on permission.Code equals roleClaim.ClaimValue
                join userRole in _dbContext.UserRoles on roleClaim.RoleId equals userRole.RoleId
                where userRole.UserId == userId && (permission.Type.Equals("Menu") || permission.Type.Equals("Url"))
                select permission).Distinct().OrderBy(i => i.Sort).ToListAsync();
        }

        public async Task<IList<PermissionEntity>> QueryAsync(int treeType)
        {
            return await (from permission in _dbContext.Permissions
                where permission.Type.Equals("Menu") || permission.Type.Equals("Url")
                orderby permission.Sort
                select permission).ToListAsync();
        }
    }
}